<?php
	/**
	 * 数据库类
	 * @todo
	 * @author swingcoder <swingcoder@msn.com>
	 * @version 0.1
	 * @copyright Copyright (c) 2009, swingcoder.com
	 */

	if ( ! defined('_DB_LAYER') )
	{
		define( "_DB_LAYER", 1 );

		class db
		{
			var $CFG = array( "HOST"=>'', "USERNAME"=>'', "PASSWORD"=>'', "DB"=>'', "CHARSET"=>"" );
			var $LINK = null;
			var $RS = null;
			var $EFFECTEDROWS = 0;
			var $SQL = '';
			var $ERRNO = 0;
			var $ERRMSG = '';
			var $debug = true;
			var $errorlog = '';

			function db( $cfg = array() )
			{
				if( ! empty( $cfg ) )
				{
					$this->CFG = $cfg;
				}
				else
				{
					require '../inc/config.inc.php';

					$this->CFG[ 'HOST' ] = $_config[ 'db' ][ 'ip' ];
					$this->CFG[ 'DB' ] = $_config[ 'db' ][ 'database' ];
					$this->CFG[ 'USERNAME' ] = $_config[ 'db' ][ 'user' ];
					$this->CFG[ 'PASSWORD' ] = $_config[ 'db' ][ 'password' ];
					$this->CFG[ 'CHARSET' ] = $_config[ 'db' ][ 'charset' ];
				}
			}

			private function connect()
			{
				$this->LINK = mysql_connect( $this->CFG["HOST"], $this->CFG["USERNAME"], $this->CFG["PASSWORD"])  or die( $this->ERROR("connect to database failure.") );

				mysql_query( "set names '" . $this->CFG[ 'CHARSET' ] . "'", $this->LINK );

				$this->SELECT_DB( $this->CFG["DB"] );

				return $this->LINK;
			}

			private function select_db( $dbname )
			{
				mysql_select_db( $this->CFG["DB"], $this->LINK) or die( $this->ERROR() );
			}

			/**
			 * 执行sql语句单一入口
			 * select/insert/update/delete
			 * @param string sql
			 * @param string style 附加参数:array返回字段名为下标数组,row返回字段数字序号为下标数组,all返回两者
			 * @param string is_unique 是否只返回一条记录
			 * @return int|array
			 */
			public function query( $sql, $style = 'array', $is_unique = false )
			{
				$result = array();
				$this->SQL = trim( $sql );

				if ( ! is_resource( $this->LINK ) )
				{
					$this->connect();
				}

				if( preg_match( "/^select/i", $this->SQL ) )
				{
					$result = $this->select( $this->SQL, $style, $is_unique );
				}
				else
				{
					$result = $this->command( $this->SQL, $style );
				}

				return $result;
			}

			/**
			 * 更新操作
			 * insert/update/delete
			 * @param string sql
			 * @return int effected rows
			 */
			private function command( $sql = '', $style = '' )
			{
				$this->RS = mysql_query( $sql, $this->LINK ) or die( $this->ERROR() );

				return $this->get_numrow();
			}

			/**
			 * 查询操作
			 *
			 * @param string $sql
			 * @param integer $style=array|row|all
			 * @return array
			 */
			private function select( $sql, $style = 'array', $is_unique = false )
			{
				$data = array();

				$this->RS = mysql_query( $sql, $this->LINK ) or die( $this->ERROR() );
				if ( $style == 'array' )
				{
					$data = $this->fetch_array();
				}
				else if ( $style == 'row'  )
				{
					$data = $this->fetch_row();
				}
				else
				{
					$data = $this->fetch_array_all();
				}

				if ( $is_unique && count( $data ) == 1 )
				{
					$tmp = $data[0];
					$data = $tmp;
					$data[0] = $tmp;
				}

				return $data;
			}

			private function fetch_row()
			{
				$rowarr = array();

				if ( is_resource( $this->RS ) )
				{
					while( $row = mysql_fetch_row( $this->RS ) )
					{
						$rowarr[] = $row;
					}
				}

				return $rowarr;
			}

			private function fetch_array()
			{
				$rowarr = array();

				if ( is_resource( $this->RS ) )
				{
					while( $row = mysql_fetch_array( $this->RS,MYSQL_ASSOC ) )
					{
						$rowarr[] = $row;
					}
				}

				return $rowarr;
			}

			private function fetch_array_all()
			{
				$rowarr = array();

				if ( is_resource( $this->RS ) )
				{
					while( $row = mysql_fetch_array( $this->RS, MYSQL_ASSOC ) )
					{
						$rowarr[] = $row;
					}
				}

				return $rowarr;
			}

			/**
			 * 获取sql操作影响的行数
			 */
			private function get_numrow()
			{
				if( ! preg_match( "/^select/", $this->SQL ) )
				{
					$this->EFFECTEDROWS =  mysql_affected_rows( $this->LINK );
				}
				else
				{
					$this->EFFECTEDROWS =  mysql_num_rows( $this->RS );
				}

				return $this->EFFECTEDROWS;
			}

			/**
			 * 获取insert的自增长id
			 */
			public function get_insert_id()
			{
				return mysql_insert_id( $this->LINK );
			}

			public function begin_transaction()
			{
				mysql_query( "SET AUTOCOMMIT=0", $this->LINK ) or die( $this->ERROR() );
			}

			public function commit_transaction()
			{
				mysql_query( "commit",$this->LINK ) or die( $this->ERROR() );
			}

			public function rollback_transaction()
			{
				mysql_query( "rollback",$this->LINK ) or die( $this->ERROR() );
			}

			private function error( $msg = '' )
			{
				$this->ERRMSG = mysql_error( $this->LINK );
				if( empty( $this->ERRMSG ) )
				{
					if( empty( $msg ) )
					{
						return false;
					}
					else
					{
						$s = $msg;
					}
				}
				else
				{
					$s = $msg;
					$s .= "<p>SQL Debug Trace:</p>";
					$s .= "<p><font color='red'>SQL:</font> ".$this->SQL."</p>\n";
					$s .= "<p><font color='red'>Error:</font> ".$this->ERRMSG."</p>\n";
					$info = debug_backtrace();
					$s .= "<table border='1'>";
					foreach($info as $err_idx=>$err_row)
					{
						$s .= "<tr><td rowspan='4' width='25' valign='absmiddle'>$err_idx</td></tr>";
						$s .= "<tr><td>文件名:".$err_row["file"]."</td></tr>";
						$s .= "<tr><td>行号:".$err_row["line"]."</td></tr>";
						$s .= "<tr><td>函数:".$err_row["function"]."</td></tr>";
					}
					$s .= "</table>";
				}
				if( $this->debug )
				{
					echo $s;
				}
				else
				{
					error_log( '[' . date('Y-m-d H:i:s') . '] ' . $this->SQL .' | ' . $this->ERRMSG . "\r\n", 3, $this->errorlog);
				}
			}

			private function close_db()
			{
				if( is_resource($this->RS) )
				{
					mysql_free_result( $this->RS ) or die( $this->ERROR() );
				}
				if( $this->LINK )
				{
					mysql_close( $this->LINK ) or die( $this->ERROR() );
				}
			}

			 function __destruct()
			 {
				 if( is_resource( $this->LINK ) )
				 {
					$this->close_db();
				 }
			 }
		}
	}
?>